import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Fractal implements ActionListener{
	int step;
	static BufferedImage[] fractalImages = new BufferedImage[7];
	static{
		for(int i = 0; i < 7; ++i){
			fractalImages[i] = new BufferedImage(720,720, BufferedImage.TYPE_4BYTE_ABGR);
			Graphics2D g = fractalImages[i].createGraphics();
			g.setColor(new Color(0,0,0,255));
			recursivePaint(g, i + 1, 0, 0, 720, 720);
			try {
				ImageIO.write(fractalImages[i], "png", new File("fractal"+i+".png"));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	public static void recursivePaint(Graphics2D g, int lod, int x, int y, int w, int h){
		if(lod <= 1){
			g.fillRect(x,  y,  Math.max(w, 1),  Math.max(h, 1));
		}
		else{
			//top left
			recursivePaint(g, lod - 1, x, y, w/3, h/3);
			//top right
			recursivePaint(g, lod - 1, x+2*w/3, y, w/3, h/3);
			//middle
			recursivePaint(g, lod - 1, x+w/3, y+h/3, w/3, h/3);
			//bottom left
			recursivePaint(g, lod - 1, x, y+2*w/3, w/3, h/3);
			//bottom right
			recursivePaint(g, lod - 1, x + 2*w/3, y + 2*w/3, w/3, h/3);
		}
	}
	
	public void paint(Graphics2D g){
		BufferedImage i1 = fractalImages[(step/256)%7];
		BufferedImage i2 = fractalImages[(step/256+1)%7];
		g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, (float)(step % 256)/256.0f));
		g.drawImage(i2, 0, 0, null);
		g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f-(float)(step % 256)/256.0f));
		g.drawImage(i1, 0, 0, null);
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		step++;
		
	}
}
